package com.lmf.mock.starter.autoconfigure.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lmf.mock.starter.autoconfigure.entity.MockApi;
import com.lmf.mock.starter.autoconfigure.mapper.MockApiMapper;
import com.lmf.mock.starter.autoconfigure.service.MockApiService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Mock接口服务实现类
 */
@Service
public class MockApiServiceImpl extends ServiceImpl<MockApiMapper, MockApi> implements MockApiService {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public List<MockApi> getApisByGroupId(Long groupId) {
        QueryWrapper<MockApi> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_id", groupId)
                   .eq("enabled", true)
                   .orderByAsc("sort_order", "id");
        return list(queryWrapper);
    }

    @Override
    public MockApi getApiByPathAndMethod(String path, String method) {
        QueryWrapper<MockApi> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("api_path", path)
                   .eq("http_method", method.toUpperCase())
                   .eq("enabled", true);
        return getOne(queryWrapper);
    }

    @Override
    public MockApi getApiByPathMethodAndParams(String path, String method, Map<String, Object> requestParams) {
        QueryWrapper<MockApi> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("api_path", path)
                   .eq("http_method", method.toUpperCase())
                   .eq("enabled", true)
                   .orderByAsc("sort_order", "id");
        
        List<MockApi> apis = list(queryWrapper);
        
        // 如果没有找到任何API，返回null
        if (apis.isEmpty()) {
            return null;
        }

        // 将paramMatchRules为null的排到最后，优先按照规则匹配
        apis = apis.stream().sorted(Comparator.comparing(
                MockApi::getParamMatchRules,Comparator.nullsLast(Comparator.naturalOrder())
        )).collect(Collectors.toList());

        // 遍历所有匹配的API，找到参数匹配的
        for (MockApi api : apis) {
            if (isParamsMatched(api.getParamMatchRules(), requestParams)) {
                return api;
            }
        }
        
        // 如果没有找到参数匹配的，返回第一个没有参数匹配规则的API
        for (MockApi api : apis) {
            if (!StringUtils.hasText(api.getParamMatchRules())) {
                return api;
            }
        }
        
        // 如果都有参数匹配规则但都不匹配，返回第一个
        return apis.get(0);
    }

    /**
     * 检查请求参数是否匹配配置的规则
     */
    private boolean isParamsMatched(String paramMatchRules, Map<String, Object> requestParams) {
        if (!StringUtils.hasText(paramMatchRules)) {
            // 没有配置参数匹配规则，则认为匹配
            return true;
        }
        
        try {
            Map<String, Object> rules = objectMapper.readValue(paramMatchRules, new TypeReference<Map<String, Object>>() {});
            
            // 检查所有规则是否都匹配
            for (Map.Entry<String, Object> rule : rules.entrySet()) {
                String paramName = rule.getKey();
                Object expectedValue = rule.getValue();
                Object actualValue = requestParams.get(paramName);
                
                if (!isValueMatched(expectedValue, actualValue)) {
                    return false;
                }
            }
            
            return true;
        } catch (Exception e) {
            // JSON解析失败，认为不匹配
            return false;
        }
    }

    /**
     * 检查值是否匹配
     */
    private boolean isValueMatched(Object expectedValue, Object actualValue) {
        if (expectedValue == null && actualValue == null) {
            return true;
        }
        if (expectedValue == null || actualValue == null) {
            return false;
        }
        
        // 转换为字符串进行比较
        String expected = String.valueOf(expectedValue);
        String actual = String.valueOf(actualValue);
        
        return expected.equals(actual);
    }

    @Override
    public boolean createApi(MockApi api) {
        if (api.getSortOrder() == null) {
            api.setSortOrder(0);
        }
        if (api.getEnabled() == null) {
            api.setEnabled(true);
        }
        if (api.getStatusCode() == null) {
            api.setStatusCode(200);
        }
        if (api.getDelayMs() == null) {
            api.setDelayMs(0);
        }
        return save(api);
    }

    @Override
    public boolean updateApi(MockApi api) {
        return updateById(api);
    }

    @Override
    public boolean deleteApi(Long id) {
        return removeById(id);
    }

    @Override
    public boolean toggleApiStatus(Long id, boolean enabled) {
        MockApi api = new MockApi();
        api.setId(id);
        api.setEnabled(enabled);
        return updateById(api);
    }
}
